package com.riant.dayo2.demo2;
import	java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Classname Demo
 * @Description TODO
 * @Date 2021/2/26 23:05
 * @Created by 张斌
 */
public class Demo {
    public static void main(String[] args) {
        testPerson();
        testPerson1();
    }
    /**
     * 通过反射获取类的属性、方法、构造函数
     * */
    public static void testPerson(){
        try{
            Class<?> clas=  Class.forName("com.riant.dayo2.demo2.Person");
            //反射获取构造结构
            Field[] field1=clas.getFields();//获得所有的public属性
            Field[] field2=clas.getDeclaredFields();//获得所有的属性：public、protected、private
            for (Field field:field2) {
                System.out.println("person 的属性是"+field.toString());//获得完整属性名
            }
            Method[] method1=clas.getMethods();//获得所有的public方法
            Method[] method2=clas.getDeclaredMethods();//获得所有的方法：public、protected、private
            for (Method method:method2) {
                System.out.println("person 的方法是"+method.toString());//获得完整方法名
            }
            Constructor[] constructors1=clas.getConstructors();
            Constructor[] constructors2=clas.getDeclaredConstructors();
            for (Constructor constructor:constructors1) {
                System.out.println("person 的构造方法是"+constructor.toString());//获得完整构造方法名
            }
            for (Constructor constructor:constructors2) {
                System.out.println("person 的构造方法是"+constructor.toString());//获得完整构造方法名
            }
            System.out.println("========================================================");
            //2、修改类的属性
            /**
             * 当Person没有无参构造方法时，会初始化失败报错：
             * java.lang.InstantiationException: com.riant.dayo2.demo2.Person
             * */
            Person person= (Person) clas.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void testPerson1(){
        try{
            Class<Person> clas= (Class<Person>) Class.forName("com.riant.dayo2.demo2.Person");
            Person person= (Person) clas.newInstance();
            //通过获取属性改变实例的属性
            Field field=clas.getDeclaredField("name");
            field.setAccessible(true);//当为true时，压制该object的jvm可见性安全检查，false,执行jvm的可见性
            field.set(person,"zhangsan");
            System.out.println(person.getName());
            //通过反射获取Method，并调用方法
            Method method = clas.getDeclaredMethod("setAge", int.class);
            //Method.invoke(object,args):前面时对象，后面是参数
            method.invoke(person,20);
            System.out.println(person.getAge());
            Method getMethod=clas.getMethod("getAge");
            System.out.println(getMethod.invoke(person));

            Class<?> clas2=  Class.forName("com.riant.dayo2.demo2.Person");
            Constructor<Person>  constructor= (Constructor<Person>) clas2.getDeclaredConstructor(String.class,int.class);
            Person person1= constructor.newInstance("lisi",18);
            System.out.println(person1.toString());
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
